<template>
  <div class="search">
    <van-search
      v-model="value"
      show-action
      background="#4fc08d"
      placeholder="请输入搜索关键词"
      @search="onSearch"
      @cancel="onCancel"
      @input="think"
    >
      <template #default>
        <span class="qux" @click="quxiao">取消</span>
      </template>
    </van-search>
    <!-- 联想区域 -->
    <van-cell-group v-if="thinkList.length != 0">
      <van-cell title="联想区域" />
      <van-cell
        v-for="(item, index) in thinkList"
        :key="index"
        icon="search"
        @click="onSearch(item.oldItem)"
      >
        <template #title> <span v-html="item.newItem"></span> </template
      ></van-cell>
    </van-cell-group>

    <!-- 搜索历史区域 -->

    <van-cell-group v-else>
      <van-cell title="搜索历史区域">
        <template #default>
          <van-icon name="delete" @click="delAll" />
        </template>
      </van-cell>
      <van-cell
        icon="search"
        :title="item"
        v-for="(item, index) in historyList"
        :key="index"
        @click="onSearch(item)"
      >
        <template #default>
          <van-icon name="cross" @click.stop="delList(index)" />
        </template>
      </van-cell>
    </van-cell-group>
  </div>
</template>

<script>
/*
搜索 - 创建组件
  a.在home下面的新建search文件夹/search.vue
  b.在router/index下面导入和配置路由,home.vue下面to="/search"

  搜索 - 完成结构 & 样式
  a.在官网找到Search 搜索,取消需要设置样式,浏览器:hov勾选:active复制样式进行修改
  c.联想区域和搜索历史区域,用到了Cell 单元格,以及插槽的使用


  搜索 - 数据搜索
    a.先新建一个searchResult文件夹以及vue文件,路由配置跟home同一级路由,动态路由:key,
    b.再到本页面设置一个onSearch方法,value就是输入的参数,利用this.$router.push(`/searchResult/${value}`)进行页面传值
    c.搜索结果页面接收用{{route.params.key}}


搜索 - 完成联想
  a.给输入框添加一个input事件
  b.在data里面设置一个联想存储数据,
  c.给联想添加方法,向服务器发送请求(封装api)
  d.渲染到联想区域页面


  联想和搜索历史区域相互隐藏  用v-if 判断thinkList的长度不等于0 就显示联想区域 v-else就显示历史区域


搜索 - 点击联想跳转
  a.给每个联想区域添加点击事件,因为跟onSearch 跳转搜索页面的逻辑是一样的,所以点击的就是@click="onSearch(item)",

搜索 - 关键字高亮
  a.在赋值那里遍历每个元素,map,然后return 每个值,用replace(要替换的元素,新元素),用span标签包着,style行内改高亮的颜色
  b.发现问题,在页面联想时,连标签也解析出来了,利用v-html来解析
  c.改进改成对象,oldItem,newItem,点击时old,跳转渲染时用newItem


  搜索 - 判断搜索内容为空
    a.判断value的长度是否为空,为空就把联想区域数组清空,return终止

  搜索-取消
  a.清空value 调用think()



  搜索 - js 的抖动
    a每次执行完之后都要清空定时器,在外面clearTime
    b.把逻辑代码都报到定时器里面
    c.async要写到异步的前面,否则会出错

搜索 - 保存 & 获取 & 渲染搜索历史
  a.要先data定义一个数组储存数据,再到onSearch里面往定义的数组push,因为没有保存到本地,所有页面一刷新就没有数据了
  b.导入token方法,获取和保存,先保存到本地,再到定义变量里判断,如果有就取出,没有就用默认的数据,在渲染到搜索历史区域里

搜索 - 排序 & 去重
  a.将push改为unshift,每次添加都在最前面
  b.因为添加相同的搜索数据都会显示,这样很奇怪,利用...new Set去重,也有连接数组的作用

 搜索 - 点击历史数据跳转
   a.给每个历史数据添加点击事件
   b.跟点击联想的跳转一样的逻辑,但是不能用,有bug,在去一个名字

 删除单个历史记录
   a.给每个叉叉添加点击事件携带index下标
   b.历史记录 数组利用splice删除对应的下标
   c.把删除的保存到本地 
   d.事件冒泡,每次点击会跳转页面,stop阻止

   搜索 - 清空历史数据
    a.给垃圾桶添加点击事件
    b.到官网找弹出框提示
    c.在.then写逻辑代码,清空历史数组,删除本地数据  catch提示取消

    还有一个bug,输入框连续输入,在不停连续删除,会报错400,把那段判断放到定时器里面
   

*/
import { apiThink } from '@/api/search.js'
import { setLocal, getLocal, removeLocal } from '@/utils/local.js'

export default {
  data () {
    return {
      value: '', //搜索结果的双向绑定
      thinkList: [], // 联想的数据源
      timeId: null, //防抖的定时器
      historyList: getLocal('history') || [] //搜索历史  获取
    }
  },
  methods: {
    // 联想数据
    onSearch (value) {
      // 不能加this 因为是参数,不是搜索的双向绑定
      if (value.trim() === '') {
        return
      }
      // 跳转到搜索页面
      this.$router.push(`/serachResult/${value}`)
      // 将搜索结果保存到数组中,保存到本地,unshift每次添加都在最前面
      this.historyList.unshift(this.value)
      //  去重
      this.historyList = [...new Set(this.historyList)]

      setLocal('history', this.historyList)
      
      
    },
    // // 历史数据跳转
    // onSearchh (value) {
    //   // 跳转到搜索页面
    //   this.$router.push(`/serachResult/${value}`)
    //   // 将搜索结果保存到数组中,保存到本地,unshift每次添加都在最前面
    //   this.historyList.unshift(this.value)
    //   //  去重
    //   this.historyList = [...new Set(this.historyList)]

    //   setLocal('history', this.historyList)
    // },
    //内置取消的方法
    onCancel () {},
    // 联想数据
    think () {
      clearTimeout(this.timeId)
      this.timeId = setTimeout(async () => {
        //判断内容是否为空,为空就清空内容,终止下面的逻辑代码
        if (this.value.length === 0) {
          this.thinkList = []
          return
        }
        //联想input事件
        const res = await apiThink(this.value)
        // console.log(res) 高亮,遍历,替换
        this.thinkList = res.data.data.options.map(item => {
          return {
            oldItem: item,
            newItem: item.replace(
              this.value,
              `<span style="color: pink">${this.value}</span>`
            )
          }
        })
      }, 500)
    },
    // 点击取消 清空输入框,调用think方法
    quxiao () {
      this.value = ''
      this.think()
    },
    //删除单个历史记录,先删除对应的下标,在保存在本地
    delList (index) {
      this.historyList.splice(index, 1)
      setLocal('history', this.historyList)
    },
    //清除历史区域记录,.then清空历史数组,removeLocal删除,.catch
    delAll () {
      this.$dialog
        .confirm({
          title: '温馨提示',
          message: '你确定要清除历史记录?'
        })
        .then(() => {
          this.historyList = []
          removeLocal('history')
        })
        .catch(() => {
          this.$toast('取消')
        })
    }
  }
}
</script>

<style lang="less" scoped>
.search {
  /deep/ .van-search__action {
    color: #fff;
    // background-color: green;
  }
  .van-search__action:active {
    background-color: green;
  }
}
</style>
